package main

import (
	"github.com/BurntSushi/toml"
	"github.com/garyburd/redigo/redis"
	"github.com/kataras/iris"
	"github.com/ngaut/log"
	"server/kline/model"
	"time"
	"sync"
)

var bk *Kline

type Kline struct {
	sync.Mutex
	startTime 		time.Time
	config    		*Configuration
	redisPool 		map[string]*redis.Pool
	data      		*Data

	klineWorkers 	map[string]*klineWorker
	depths 			map[string]*Depth
}

func (k *Kline) RegistKlineWorker(key string, worker *klineWorker)  {
	if _, ok := k.klineWorkers[key]; !ok {
		k.Lock()
		k.klineWorkers[key] = worker
		k.Unlock()
	}
}

func (k *Kline) RegistDepth(key string, depth *Depth)  {
	if _, ok := k.depths[key]; !ok {
		k.Lock()
		k.depths[key] = depth
		k.Unlock()
	}
}

func (k *Kline) bootstrap() {
	// log
	k.config.Log.Setting()

	// redis
	for key, conf := range k.config.Redis {
		k.redisPool[key] = conf.redisPool()
	}

	// db
	// 目前只考虑主库情况
	if dbConfig, ok := k.config.Db["main"]; ok {
		model.InitMainDB(dbConfig.FormatDBConnection())
		log.Infof("main database configuration ok, host: %s, port: %d, username: %s, dbname: %s",
			dbConfig.Host, dbConfig.Port, dbConfig.Username, dbConfig.DBName)
	} else {
		log.Fatalf("database connect error, check configuration")
	}
}

func (k *Kline) GetRedisPool(key string) *redis.Pool {
	if pool, ok := k.redisPool[key]; ok {
		return pool
	}
	return nil
}

// init default data
func (k *Kline) initialize() {
	k.startTime = time.Now()
	k.data = NewData()
	if log.GetLogLevel() == log.LOG_LEVEL_DEBUG {
		// coin pair data
		for k, pair := range k.data.CoinPair {
			log.Debugf("[%s]: %+v", k, pair)
		}
	}
}

func (k *Kline) start() {
	manager := new(manager)
	manager.run(k)
}

func server() {

	config := loadConfiguration()

	// 1. new kline
	k := Kline{
		config:    		&config,
		redisPool: 		make(map[string]*redis.Pool),
		klineWorkers: 	make(map[string]*klineWorker),
		depths: 		make(map[string]*Depth),
	}

	// 2. init
	k.bootstrap()

	k.initialize()

	// 3. start server
	k.start()

	bk = &k

	app := iris.New()
	registApiRoutes(app)
	app.Run(iris.Addr(k.config.Http.GetAddr()))

}

func loadConfiguration() Configuration {

	// decode toml file
	configuration := newConfiguration()
	_, err := toml.DecodeFile(CONFIG_FILE, &configuration)
	if err != nil {
		panic(err.Error())
	}

	return configuration
}
